package com.xx.aop;

import com.xx.entity.User;
import com.xx.service.impl.UserServiceImpl;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.logging.Logger;

@Component  //定义组件，交由spring管理
@Aspect     //设置当前类为AOP切面类
public class MyAdvice {

    private static final Logger logger = Logger.getLogger(String.valueOf(UserServiceImpl.class));
//    @Pointcut("execution(void com.xx.service.impl.BookServiceImpl.addBook(String,String,Double))")
    @Pointcut("execution(void com.xx.service.impl.*.*(..))")
    private void pt(){

    }
    //制作切面
    @Before("pt()")
    public void method(){
        System.out.println("AOP开始时间:" + System.currentTimeMillis());
    }

    @Before("pt()")
    /*JoinPoint:代表了程序执行的某个具体位置，比如方法的调用、异常的抛出等。
    AOP框架通过拦截这些Joinpoint来插入额外的逻辑，实现横切关注点的功能*/
    public void beforeMethod(JoinPoint joinPoint){
        System.out.println("当前调用的类:"+joinPoint.getSignature()+
                "调用的方法是什么:"+joinPoint.getSignature().getName());
        System.out.println("传递的参数:");
        List<Object>list = Arrays.asList(joinPoint.getArgs());
        list.stream().forEach(o -> System.out.println(o));
    }

    @After("pt()")
    public void afterMethod(){
        System.out.println("AOP结束时间:" + System.currentTimeMillis());
    }


    /**
     * 环绕通知
     * 对原始的调用可以不接受返回值，通知方法设置成void 即可，如果接受返回值
     */
    @Around("pt()")
    public Object aroundMethod(ProceedingJoinPoint pj ) throws Throwable{

        System.out.println("around before 开始 ...");
        System.out.println("环绕通知: 1"+pj.getTarget());
        System.out.println("环绕通知: 1"+pj.getSignature().getName());
        //获取参数
        System.out.println("传入参数: "+pj.getArgs());
        //表示对原始操作的调用
        Object proceed = pj.proceed();

        System.out.println("around after 结束 ...");
        return proceed;
    }

}
